"""Build Expression Set


.. helpdoc::
This widget builds an Expression Set signal from component data.  The Expression Set, or eSet, is used by a variety of bioinformatics tools to work with expression data.  The set consists of some key parts, these are the expression data (often in a matrix or table format), phenotypic data of each sample for which expression values are calculated, and annotation data that discribes the probes that were used to assess expression.  

"""


"""<widgetXML>
    <name>
        Build Expression Set
    </name>
    <icon>
        default.png
    </icon>
    <summary>
        Generates an expression set.
    </summary>
    <tags>
        <tag priority="10">
            Bioinformatics
        </tag>
    </tags>
    <author>
        <authorname>Kyle R. Covington</authorname>
        <authorcontact>kyle@red-r.org</authorcontact>
    </author>
    </widgetXML>
"""

from OWRpy import * 
import redRGUI, signals
def setempty(obj):
    obj.setStyleSheet("QLabel { background-color: %s }" % '#00ffff')
def setfull(obj):
    obj.setStyleSheet("QLabel { background-color: %s }" % '#00ff00')
class buildEset(OWRpy): 
    globalSettingsList = ['commit']
    def __init__(self, **kwargs):
        OWRpy.__init__(self, **kwargs)
        self.RFunctionParam_object = ''
        self.RFunctionParam_phenodata = ''
        self.RFunctionParam_phenoMetadata = ''
        self.setRvariableNames(["eset"])
        
        """.. rrsignals::
            :description: `A data table read in by the widget`"""
        self.inputs.addInput('id0', 'Expression Data', [signals.affy.ESet, signals.base.RMatrix], self.processobject)
        self.inputs.addInput('id1', 'Phenotype Data', signals.base.RDataFrame, self.processPhenoData)
        self.inputs.addInput('id2', 'Phenotype Meta Data', signals.base.RDataFrame, self.processPhenoMetaData)
        self.outputs.addOutput('eset', 'Expression Set', signals.affy.ESet)
        
        self.gui_phenodatastatus = redRGUI.base.widgetLabel(self.controlArea, label = "Phenotype Data")
        setempty(self.gui_phenodatastatus)
        self.gui_phenoMetastatus = redRGUI.base.widgetLabel(self.controlArea, label = "Phenotype Meta Data")
        setempty(self.gui_phenoMetastatus)
        self.gui_expressionDatastatus = redRGUI.base.widgetLabel(self.controlArea, label = "Expression Data")
        setempty(self.gui_expressionDatastatus)
        self.gui_anntation = redRGUI.base.lineEdit(self.controlArea, label = "Annoation Type", toolTip = "Enter the annotation type coresponding to the chip used, eg; hgu95av2, or hgu133a.  This might cause problems if not entered correctly, but don't worry, just enter it corrently and move on")
        
        redRGUI.base.commitButton(self.controlArea, label = "Commit", callback = self.commitFunction)
    
    def processobject(self, data):
        if data:
            self.RFunctionParam_object=str(data.getData())
            setfull(self.gui_expressionDatastatus)
        else: 
            self.RFunctionParam_object = ''
            setempty(self.gui_expressionDatastatus)
    def processPhenoData(self, data):
        if data:
            self.RFunctionParam_phenodata = str(data.getData())
            setfull(self.gui_phenodatastatus)
        else: 
            self.RFunctionParam_phenodata = ''
            setempty(self.gui_phenodatastatus)
    def processPhenoMetaData(self, data):
        if data:
            self.RFunctionParam_phenoMetadata = str(data.getData())
            setfull(self.gui_phenoMetastatus)
        else: 
            self.RFunctionParam_phenoMetadata = ''
            setempty(self.gui_phenoMetastatus)
    def commitFunction(self):
        if self.RFunctionParam_object == '': return
        if self.R('class(%s)' % self.RFunctionParam_object, wantType = redR.NOCONVERSION) in ['data.frame', 'matrix']:
            """This is the case where something that is not an eSet is attached to the widget, we must build the eSet and send that"""
            inj = []
            if self.RFunctionParam_phenodata != '':
                if self.RFunctionParam_phenoMetadata != '':
                    inj.append(', phenoData = new("AnnotatedDataFrame", data = %s, varMetadata = %s)' % (self.RFunctionParam_phenodata, self.RFunctionParam_phenoMetadata))
                else:
                    inj.append(', phenoData = new("AnnotatedDataFrame", data = %s)' % self.RFunctionParam_phenodata)
            if self.gui_anntation.text() != '':
                inj.append(', annotation = "%s"' % self.gui_anntation.text())
                
            self.R('%(newdata)s<-new("ExpressionSet", exprs = %(exprs)s %(inj)s")' {'newdata': self.Rvariables['eset'], 'exprs': self.RFunctionParam_object, 'inj':''.join(inj)}, wantType = redR.NOCONVERSION)
            newdata = signals.affy.ESet(self, data = self.Rvariables['eset'])
            self.rSend('eset', newdata)
        else: 
            """The only other case is that an eset was already attached, so we just need to modify it"""
            if self.RFunctionParam_phenodata != '':
                if self.RFunctionParam_phenoMetadata != '':
                    self.R('phenoData(%(eset)s) <- new("AnnotatedDataFrame", data = %(pheno)s, varMetadata = %(meta)s)' % {'eset':self.RFunctionParam_object, 'pheno':self.RFunctionParam_phenodata, 'meta':self.RFunctionParam_phenoMetadata}, wantType = redR.NOCONVERSION)
                else:
                    self.R('phenoData(%(eset)s) <- new("AnnotatedDataFrame", data = %(pheno)s)' % {'eset':self.RFunctionParam_object, 'pheno':self.RFunctionParam_phenodata}, wantType = redR.NOCONVERSION)
            if self.gui_anntation.text() != '':
                self.R('annotation(%(eset)s) <- "%(annot)s"' % {'eset':self.RFunctionParam_object, 'annot':self.gui_anntation.text()}, wantType = redR.NOCONVERSION)
                
            newdata = signals.affy.ESet(self, data = self.RFunctionParam_object)
            self.rSend('eset', newdata)
        

